package com.xyz.FileTest.ZipTest;

import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class Main {
    public static void main(String[] args) throws IOException {
        //zipFiles("out/production/IOLearning/com/xyz/FileTest/ZipTest/1.zip","src/com/xyz/FileTest/ZipTest");
        unZip();
    }

    //压缩指定文件夹中的所有文件到一个zip文件中
    // 参数 1： zipFilePath 压缩文件的路径
    // 参数 2:  zipPath 要压缩的文件夹路径
    public static void zipFiles(String zipFilePath,String zipPath) throws IOException {
        //通过 try （） 结构，创建用于压缩的 ZipOutputStream 类对象 zip,
        // 改类本身是一个 Filter 模式构建的有附加功能的类，所以构造器参数要用 FileOutputStream 对象
        // 实际上就是对 FileOutputStream 功能进行包装，加入压缩功能
        // 创建出压缩文件
        try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            // 指定用来压缩的文件夹，用 文件对象获取
            File f = new File(zipPath);
            // 创建文件数组 files,获取上面对象遍历文件和子目录的文件对象
            File[] files = f.listFiles(); // 列出所有文件和子目录
            // 遍历指定要进行压缩的文件数组
            for (File file : files) {
                // 通过压缩输出流对象的 putNextEntry,将普通文件转换为压缩文件
                zip.putNextEntry(new ZipEntry(file.getName()));
                // 通过 write 方法，将压缩文件写入压缩包中
                zip.write(getFileDataAsBytes(file));
                // 关闭压缩文件，释放资源
                zip.closeEntry();
            }
        }

    }

    //按字节读取文件到字节数组
    // 输入参数是一个文件对象
    public static byte[] getFileDataAsBytes(File f) {
        //设置一个字节数组，大小正好能存下指定参数文件的内容
        byte[] data = new byte[(int) f.length()];
        //通过文件输入流，读取该文件到字节数组中
        try (InputStream is = new FileInputStream(f)) {
            int n;
            while ((n = is.read(data)) != -1) {
                System.out.println("读取了 " + n + " 字节");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    // 解压
    public static void unZip() throws IOException{
        //首先指定压缩文件
        //用普通的文件输入流对象，创建出压缩文件输入流对象，用来解压压缩文件包
        try (ZipInputStream zip = new ZipInputStream(new FileInputStream("out/production/IOLearning/com/xyz/FileTest/ZipTest/1.zip"))) {
            // 创建单个压缩文件对象
            ZipEntry entry = null;
            // 通过循环，读取单个压缩文件 getNextEntry
            while ((entry = zip.getNextEntry()) != null) {
                // 获取文件名
                String name = entry.getName();
                if (!entry.isDirectory()) {
                    int n;
                    while ((n = zip.read()) != -1) {
                        System.out.print((char)n);
                    }
                }
            }
        }
    }

}
